/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * File Name          : freertos.c
  * Description        : Code for freertos applications
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "uart_comm.h"




/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
// 任务属性定义（确保在 MX_FREERTOS_Init 前声明）
const osThreadAttr_t uartReceiveTask_attributes = {
  .name = "UART_Receive",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityHigh,
};

const osThreadAttr_t uartTransmitTask_attributes = {
  .name = "UART_Transmit",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityNormal,
};

const osThreadAttr_t sysInfoTask_attributes = {
  .name = "SysInfo",
  .stack_size = 256 * 4,
  .priority = (osPriority_t) osPriorityBelowNormal,
};

const osThreadAttr_t task1_attributes = {
  .name = "Task1",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityNormal,
};

const osThreadAttr_t task2_attributes = {
  .name = "Task2",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityNormal,
};

const osThreadAttr_t task3_attributes = {
  .name = "Task3",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityNormal,
};

const osThreadAttr_t task4_attributes = {
  .name = "Task4",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityNormal,
};


void SysInfo_Task(void* argument);
void Task1(void* argument);
void Task2(void* argument);
void Task3(void* argument);
void Task4(void* argument);




/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */

/* USER CODE END Variables */
/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
  .name = "defaultTask",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityNormal,
};

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */

/* USER CODE END FunctionPrototypes */

void StartDefaultTask(void *argument);

void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

/**
  * @brief  FreeRTOS initialization
  * @param  None
  * @retval None
  */
void MX_FREERTOS_Init(void) {
  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* USER CODE BEGIN RTOS_MUTEX */
  /* add mutexes, ... */
  /* USER CODE END RTOS_MUTEX */

  /* USER CODE BEGIN RTOS_SEMAPHORES */
  /* add semaphores, ... */
  /* USER CODE END RTOS_SEMAPHORES */

  /* USER CODE BEGIN RTOS_TIMERS */
  /* start timers, add new ones, ... */
  /* USER CODE END RTOS_TIMERS */

  /* USER CODE BEGIN RTOS_QUEUES */

  /* USER CODE END RTOS_QUEUES */

  /* Create the thread(s) */
  /* creation of defaultTask */
  defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);

  /* USER CODE BEGIN RTOS_THREADS */
    // 创建全局空闲帧队列
    free_frame_queue = osMessageQueueNew(FREE_FRAME_QUEUE_SIZE, sizeof(DataFrame_t*), NULL);
    
    // 创建USART1队列
    usart1_resource.rx_queue = osMessageQueueNew(RX_QUEUE_SIZE, sizeof(DataFrame_t*), NULL);
    usart1_resource.tx_queue = osMessageQueueNew(TX_QUEUE_SIZE, sizeof(DataFrame_t*), NULL);
    
    // 创建USART3队列
    usart3_resource.rx_queue = osMessageQueueNew(RX_QUEUE_SIZE, sizeof(DataFrame_t*), NULL);
    usart3_resource.tx_queue = osMessageQueueNew(TX_QUEUE_SIZE, sizeof(DataFrame_t*), NULL);
    
    // 初始化缓冲区
    UARTCOM_InitBuffers();
    
    // 初始化串口资源
    UARTCOM_InitUARTResource(&usart1_resource);
    UARTCOM_InitUARTResource(&usart3_resource);
    
    // 创建任务
    osThreadNew(UARTCOM_ReceiveTask, NULL, &uartReceiveTask_attributes);
    osThreadNew(UARTCOM_TransmitTask, (void*)&usart1_resource, &uartTransmitTask_attributes);
    osThreadNew(UARTCOM_TransmitTask, (void*)&usart3_resource, &uartTransmitTask_attributes);
    osThreadNew(SysInfo_Task, NULL, &sysInfoTask_attributes);
    osThreadNew(Task1, NULL, &task1_attributes);
    osThreadNew(Task2, NULL, &task2_attributes);
    osThreadNew(Task3, NULL, &task3_attributes);
    osThreadNew(Task4, NULL, &task4_attributes);
  
  /* USER CODE END RTOS_THREADS */

  /* USER CODE BEGIN RTOS_EVENTS */
  /* add events, ... */
  /* USER CODE END RTOS_EVENTS */

}

/* USER CODE BEGIN Header_StartDefaultTask */
/**
  * @brief  Function implementing the defaultTask thread.
  * @param  argument: Not used
  * @retval None
  */
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
  /* USER CODE BEGIN StartDefaultTask */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1000); // 适度延时释放CPU
  }
  /* USER CODE END StartDefaultTask */
}

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
/*******************************************************************************
 *                              应用任务函数
 ******************************************************************************/
//注意！
	//1.任务的发送间隔时间不能一样，否则出现粘包。

// 系统信息报告任务
void SysInfo_Task(void* argument) {
    for(;;) {
        char report[200];
        snprintf(report, sizeof(report),
            "\r\n--- System Status ---\r\n"
            "Uptime: %d seconds\r\n"
            "Free Heap: %u bytes\r\n"
            "Active Tasks: %lu\r\n"
            "USART1 Rx Queue: %u/%u, Tx Queue: %u/%u\r\n"
            "USART3 Rx Queue: %u/%u, Tx Queue: %u/%u\r\n"
            "Free Frames: %u/%u\r\n",
            (int)(osKernelGetTickCount() / 1000),
            (unsigned int)xPortGetFreeHeapSize(),
            (unsigned long)uxTaskGetNumberOfTasks(),
            (unsigned int)osMessageQueueGetCount(usart1_resource.rx_queue), 
            RX_QUEUE_SIZE,
            (unsigned int)osMessageQueueGetCount(usart1_resource.tx_queue),  
            TX_QUEUE_SIZE,
            (unsigned int)osMessageQueueGetCount(usart3_resource.rx_queue), 
            RX_QUEUE_SIZE,
            (unsigned int)osMessageQueueGetCount(usart3_resource.tx_queue), 
            TX_QUEUE_SIZE,
            (unsigned int)osMessageQueueGetCount(free_frame_queue), 
            TX_POOL_SIZE);
        
        UARTCOM_SendToUART(report, &usart1_resource, false, 0xFF);
        
        osDelay(8009);
    }
}

// 应用任务1
void Task1(void* argument) {
    uint32_t count = 0;
    const uint8_t source_id = 1;
    
    for(;;) {
        count++;
        char msg[40];
        snprintf(msg, sizeof(msg), "[Task1] Run %d", count);
        
        // 发送到USART1
        UARTCOM_SendToUART(msg, &usart1_resource, false, source_id);
        
        // 发送到USART3（带LoRa地址）
        UARTCOM_SendToUART(msg, &usart3_resource, true, source_id);
        
        osDelay(3000);
    }
}

// 应用任务2
void Task2(void* argument) {
    uint32_t count = 0;
    const uint8_t source_id = 2;
    
    for(;;) {
        count++;
        char msg[40];
        snprintf(msg, sizeof(msg), "[Task2] Run %d", count);
        
        // 发送到USART1
        //UARTCOM_SendToUART(msg, &usart1_resource, false, source_id);
        
        osDelay(4000);
    }
}

// 应用任务3
void Task3(void* argument) {
    uint32_t count = 0;
    const uint8_t source_id = 3;
    
    for(;;) {
        count++;
        char msg[40];
        snprintf(msg, sizeof(msg), "[Task3] Run %d", count);
        
        // 发送到USART3（带LoRa地址）
        //UARTCOM_SendToUART(msg, &usart3_resource, true, source_id);
        
        osDelay(6000);
    }
}

// 应用任务4
void Task4(void* argument) {
    uint32_t count = 0;
    const uint8_t source_id = 4;
    
    for(;;) {
        count++;
        char msg[40];
        snprintf(msg, sizeof(msg), "[Task4] Run %d", count);
        
        // 发送到USART1
        UARTCOM_SendToUART(msg, &usart1_resource, false, source_id);
        
        osDelay(3000);
    }
}

/* USER CODE END Application */


